package cn.zhuzicc.basic.jvm.t2;

import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zhaoxiang
 * @version 1.0
 * @description 引用队列删除软引用对象
 * -Xmx20m -XX:+PrintGCDetails -verbose:gc
 * @Date 2021/9/20 17:26
 */
public class Demo2_4 {
    static final int _4M = 4 * 1024 * 1024;

    public static void main(String[] args) throws IOException {
        test2();
    }

    /**
     * 软引用
     * list --> SoftReference (这是一个强引用)
     * SoftReference --> byte[](这是一个软引用)
     */
    private static void test2() throws IOException {
        List<SoftReference<byte[]>> list = new ArrayList<>();

        // 引用队列
        final ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        for (int i = 0; i < 5; i++) {
            // 关联引用队列，当软引用所关联的 byte[] 被回收时，软引用会自己加入到 queue 中去
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4M], queue);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());
        }

        /*
            从队列中获取无用的软引用对象，并移除（引用队列中的软引用对象都是所指对象已被GC回收的对象）
            queue[
                SoftReference -> null 、SoftReference -> null、SoftReference -> null、SoftReference -> null
            ]
            list[
                SoftReference -> new byte[_4M]
            ]
         */
        Reference<? extends byte[]> poll = queue.poll();
        // poll不为null说明还有空引用对象
        while (poll != null) {
            // 引用队列不为空，则从集合中移除该元素
            list.remove(poll);
            // 移动到引用队列中的下一个元素
            poll = queue.poll();
        }

        System.out.println("============循环结束：" + list.size());
        for (SoftReference<byte[]> ref : list) {
            System.out.println(ref.get());
        }
    }
}
